﻿/*
    Project: IV:MP GUI Editor (http://code.google.com/p/ivmp-gui-editor)
    Code license: GNU Lesser GPL (http://www.gnu.org/copyleft/lesser.html) 
 */

// FIXME: Remade this all stuff and migrate functions lists to .functions FILES.

using ICSharpCode.AvalonEdit.CodeCompletion;
using ICSharpCode.AvalonEdit.Editing;
using System;
using System.Collections.ObjectModel;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace IvmpEditor
{
    public abstract class ICodeCompletion
    {
        //string Title { get; }
        public abstract ObservableCollection<ICompletionData> CompletionsList { get; }
        public virtual CompletionWindow CreateWindow(TextArea textArea)
        {
            var wnd = new CompletionWindow(textArea);
            textArea.TextEntering +=
                delegate(object sender, TextCompositionEventArgs e)
                {
                    // If user is entering a new symbol when code completion window is shown,
                    // We request insertion of currently focused element and closing window.
                    if (e.Text.Length > 0 && !char.IsLetterOrDigit(e.Text[0]))
                        wnd.CompletionList.RequestInsertion(e);
                };

            var list = this.CompletionsList;
            wnd.CompletionList.CompletionData = list;
            wnd.CompletionList.SelectedItem = list[0];

            return wnd;
        }
    }

    public class CodeCompletionItem : ICompletionData
    {
        public object Content { get; set; }
        public object Description { get; set; }
        public string Text { get; set; }
        public ImageSource Image { get; set; }
        public double Priority { get; set; }

        // Generating descripting.. TODO: add some structure for completion item infos?
        public const string 
            NO_ARGS = "()", 
            NOT_FUNCTION = null, 
            NO_RETURN = null;

        public CodeCompletionItem(string nativeName, string returnType, string arguments, string description)
        {
            Content = Text = nativeName;
            var txt = new TextBlock();
            var isConstant = arguments == NOT_FUNCTION;
            if (isConstant)
            {
                this.Image = ResourceManager.ImageConstant;
                txt.Text = string.Format("{0} {1}{2}{3}",
                    returnType, nativeName, Environment.NewLine, description);
            }
            else
            {
                this.Image = ResourceManager.ImageFunction;
                txt.Text = string.Format("{0}{1} {2}{3}{4}", 
                    returnType != NO_RETURN ? returnType + ' ' : string.Empty, 
                    nativeName, arguments, Environment.NewLine, description);
            }
            Description = txt;
        }

        public void Complete(ICSharpCode.AvalonEdit.Editing.TextArea textArea,
            ICSharpCode.AvalonEdit.Document.ISegment completionSegment, EventArgs insertionRequestEventArgs)
        {
            textArea.Document.Replace(completionSegment, this.Text);
        }
    }
}
